package com.example.launibleplugin.parser

import android.util.Log
import com.example.launibleplugin.constants.BluetoothConstants
import com.example.launibleplugin.model.DataPoint
import com.example.launibleplugin.model.DataRecord
import com.example.launibleplugin.model.DataType
import java.nio.ByteBuffer
import java.nio.ByteOrder
import java.security.MessageDigest
import java.util.UUID

/**
 * 数据解析器
 * Function: 解析从呼吸家蓝牙设备接收的数据包
 * Note: 根据呼吸家设备协议解析二进制数据
 */
class DataParser {
    
    companion object {
        private const val TAG = BluetoothConstants.LOG_TAG_PARSER
    }
    
    /**
     * Function: 解析原始数据包
     * Parameter: rawData - 原始二进制数据
     * Parameter: deviceId - 设备ID
     * Parameter: connectionId - 连接ID
     * Return: DataRecord? - 解析后的数据记录，解析失败返回null
     * Note: 主要解析入口，根据数据包格式进行解析
     */
    fun parseRawData(rawData: ByteArray, deviceId: String, connectionId: String): DataRecord? {
        try {
            Log.d(TAG, "开始解析数据包，长度: ${rawData.size}")
            Log.d(TAG, "原始数据: ${rawData.joinToString(" ") { "%02X".format(it) }}")
            
            // 验证数据包基本格式
            if (!isValidPacket(rawData)) {
                Log.w(TAG, "无效的数据包格式")
                return null
            }
            
            // 解析数据包头部
            val header = parsePacketHeader(rawData)
            if (header == null) {
                Log.w(TAG, "数据包头部解析失败")
                return null
            }
            
            // 根据数据类型解析具体内容
            val dataType = determineDataType(header.dataType)
            val parsedData = parseDataContent(rawData, header, dataType)
            val dataPoints = extractDataPoints(parsedData, dataType)
            
            // 生成校验和
            val checksum = calculateChecksum(rawData)
            
            return DataRecord(
                recordId = generateRecordId(),
                connectionId = connectionId,
                dataType = dataType,
                timestamp = System.currentTimeMillis(),
                rawData = rawData,
                parsedData = parsedData,
                dataPoints = dataPoints,
                deviceId = deviceId,
                sequenceNumber = header.sequenceNumber,
                checksum = checksum
            )
            
        } catch (e: Exception) {
            Log.e(TAG, "数据解析异常", e)
            return null
        }
    }
    
    /**
     * Function: 验证数据包格式
     * Parameter: data - 原始数据
     * Return: Boolean - 是否为有效数据包
     * Note: 检查数据包起始标识、长度等基本格式
     */
    private fun isValidPacket(data: ByteArray): Boolean {
        if (data.size < BluetoothConstants.PACKET_HEADER_SIZE + BluetoothConstants.PACKET_CHECKSUM_SIZE) {
            return false
        }
        
        // 检查起始标识
        if (data[0] != BluetoothConstants.PACKET_START_MARKER) {
            return false
        }
        
        // 检查结束标识
        if (data[data.size - 1] != BluetoothConstants.PACKET_END_MARKER) {
            return false
        }
        
        return true
    }
    
    /**
     * 数据包头部信息
     */
    private data class PacketHeader(
        val startMarker: Byte,
        val version: Byte,
        val dataType: Byte,
        val dataLength: Int,
        val sequenceNumber: Long
    )
    
    /**
     * Function: 解析数据包头部
     * Parameter: data - 原始数据
     * Return: PacketHeader? - 解析后的头部信息
     * Note: 解析数据包的头部结构
     */
    private fun parsePacketHeader(data: ByteArray): PacketHeader? {
        try {
            val buffer = ByteBuffer.wrap(data).order(ByteOrder.LITTLE_ENDIAN)
            
            val startMarker = buffer.get()
            val version = buffer.get()
            val dataType = buffer.get()
            val dataLength = buffer.get().toInt() and 0xFF
            
            // 序列号可能在后续字节中
            val sequenceNumber = if (data.size >= 8) {
                buffer.getInt().toLong()
            } else {
                0L
            }
            
            return PacketHeader(startMarker, version, dataType, dataLength, sequenceNumber)
            
        } catch (e: Exception) {
            Log.e(TAG, "头部解析异常", e)
            return null
        }
    }
    
    /**
     * Function: 确定数据类型
     * Parameter: typeCode - 类型代码
     * Return: DataType - 数据类型枚举
     * Note: 根据协议将字节码转换为数据类型
     */
    private fun determineDataType(typeCode: Byte): DataType {
        return when (typeCode.toInt() and 0xFF) {
            0x01 -> DataType.RESPIRATORY_RATE
            0x02 -> DataType.TIDAL_VOLUME
            0x03 -> DataType.MINUTE_VOLUME
            0x04 -> DataType.OXYGEN_SATURATION
            0x05 -> DataType.HEART_RATE
            0x06 -> DataType.TEMPERATURE
            0x07 -> DataType.PRESSURE
            0x08 -> DataType.FLOW_RATE
            else -> DataType.UNKNOWN
        }
    }
    
    /**
     * Function: 解析数据内容
     * Parameter: data - 原始数据
     * Parameter: header - 数据包头部
     * Parameter: dataType - 数据类型
     * Return: Map<String, Any> - 解析后的数据映射
     * Note: 根据数据类型解析具体的数据内容
     */
    private fun parseDataContent(data: ByteArray, header: PacketHeader, dataType: DataType): Map<String, Any> {
        val result = mutableMapOf<String, Any>()
        
        try {
            // 跳过头部，从数据部分开始解析
            val dataStart = BluetoothConstants.PACKET_HEADER_SIZE
            val dataEnd = data.size - BluetoothConstants.PACKET_CHECKSUM_SIZE
            val dataContent = data.sliceArray(dataStart until dataEnd)
            
            val buffer = ByteBuffer.wrap(dataContent).order(ByteOrder.LITTLE_ENDIAN)
            
            when (dataType) {
                DataType.RESPIRATORY_RATE -> {
                    if (dataContent.size >= 4) {
                        val rate = buffer.getFloat()
                        result["respiratory_rate"] = rate
                        result["unit"] = "次/分钟"
                    }
                }
                
                DataType.TIDAL_VOLUME -> {
                    if (dataContent.size >= 4) {
                        val volume = buffer.getFloat()
                        result["tidal_volume"] = volume
                        result["unit"] = "mL"
                    }
                }
                
                DataType.OXYGEN_SATURATION -> {
                    if (dataContent.size >= 4) {
                        val saturation = buffer.getFloat()
                        result["oxygen_saturation"] = saturation
                        result["unit"] = "%"
                    }
                }
                
                DataType.HEART_RATE -> {
                    if (dataContent.size >= 4) {
                        val heartRate = buffer.getFloat()
                        result["heart_rate"] = heartRate
                        result["unit"] = "次/分钟"
                    }
                }
                
                DataType.TEMPERATURE -> {
                    if (dataContent.size >= 4) {
                        val temperature = buffer.getFloat()
                        result["temperature"] = temperature
                        result["unit"] = "°C"
                    }
                }
                
                DataType.PRESSURE -> {
                    if (dataContent.size >= 4) {
                        val pressure = buffer.getFloat()
                        result["pressure"] = pressure
                        result["unit"] = "cmH2O"
                    }
                }
                
                DataType.FLOW_RATE -> {
                    if (dataContent.size >= 4) {
                        val flowRate = buffer.getFloat()
                        result["flow_rate"] = flowRate
                        result["unit"] = "L/min"
                    }
                }
                
                else -> {
                    result["raw_value"] = dataContent.joinToString(",") { it.toString() }
                    result["unit"] = "unknown"
                }
            }
            
            // 添加通用信息
            result["data_type"] = dataType.name
            result["sequence_number"] = header.sequenceNumber
            result["data_length"] = header.dataLength
            
        } catch (e: Exception) {
            Log.e(TAG, "数据内容解析异常", e)
            result["error"] = e.message ?: "解析失败"
        }
        
        return result
    }
    
    /**
     * Function: 提取数据点
     * Parameter: parsedData - 解析后的数据
     * Parameter: dataType - 数据类型
     * Return: List<DataPoint> - 数据点列表
     * Note: 将解析后的数据转换为标准数据点格式
     */
    private fun extractDataPoints(parsedData: Map<String, Any>, dataType: DataType): List<DataPoint> {
        val dataPoints = mutableListOf<DataPoint>()
        val timestamp = System.currentTimeMillis()
        
        try {
            when (dataType) {
                DataType.RESPIRATORY_RATE -> {
                    val value = parsedData["respiratory_rate"] as? Float
                    val unit = parsedData["unit"] as? String ?: ""
                    if (value != null) {
                        dataPoints.add(
                            DataPoint(
                                pointId = generatePointId(),
                                metricName = "respiratory_rate",
                                value = value,
                                unit = unit,
                                timestamp = timestamp
                            )
                        )
                    }
                }
                
                DataType.TIDAL_VOLUME -> {
                    val value = parsedData["tidal_volume"] as? Float
                    val unit = parsedData["unit"] as? String ?: ""
                    if (value != null) {
                        dataPoints.add(
                            DataPoint(
                                pointId = generatePointId(),
                                metricName = "tidal_volume",
                                value = value,
                                unit = unit,
                                timestamp = timestamp
                            )
                        )
                    }
                }
                
                // 其他数据类型的处理...
                else -> {
                    // 通用处理
                    parsedData.forEach { (key, value) ->
                        if (value is Number) {
                            dataPoints.add(
                                DataPoint(
                                    pointId = generatePointId(),
                                    metricName = key,
                                    value = value.toFloat(),
                                    unit = parsedData["unit"] as? String ?: "",
                                    timestamp = timestamp
                                )
                            )
                        }
                    }
                }
            }
        } catch (e: Exception) {
            Log.e(TAG, "数据点提取异常", e)
        }
        
        return dataPoints
    }
    
    /**
     * Function: 计算数据校验和
     * Parameter: data - 原始数据
     * Return: String - 校验和字符串
     * Note: 使用MD5算法计算数据完整性校验
     */
    private fun calculateChecksum(data: ByteArray): String {
        return try {
            val md = MessageDigest.getInstance("MD5")
            val digest = md.digest(data)
            digest.joinToString("") { "%02x".format(it) }
        } catch (e: Exception) {
            Log.e(TAG, "校验和计算异常", e)
            ""
        }
    }
    
    /**
     * Function: 生成记录ID
     * Return: String - 唯一记录ID
     * Note: 使用UUID生成唯一标识
     */
    private fun generateRecordId(): String {
        return "record_${UUID.randomUUID()}"
    }
    
    /**
     * Function: 生成数据点ID
     * Return: String - 唯一数据点ID
     * Note: 使用UUID生成唯一标识
     */
    private fun generatePointId(): String {
        return "point_${UUID.randomUUID()}"
    }
    
    /**
     * Function: 生成数据校验和
     * Parameter: data - 数据内容
     * Return: String - 校验和字符串
     * Note: 使用MD5算法生成数据校验和
     */
    private fun generateChecksum(data: ByteArray): String {
        return try {
            val md = MessageDigest.getInstance("MD5")
            val digest = md.digest(data)
            digest.joinToString("") { "%02x".format(it) }
        } catch (e: Exception) {
            Log.e(TAG, "生成校验和失败", e)
            ""
        }
    }
    
    /**
     * Function: 创建呼吸家数据记录
     * Parameter: deviceId - 设备ID
     * Parameter: connectionId - 连接ID
     * Parameter: pefValue - PEF值
     * Parameter: fev1Value - FEV1值
     * Parameter: fvcValue - FVC值
     * Parameter: timestamp - 时间戳
     * Return: DataRecord - 数据记录对象
     * Note: 根据呼吸家协议数据创建标准数据记录
     */
    fun createRespiratoryDataRecord(
        deviceId: String,
        connectionId: String,
        pefValue: Int,
        fev1Value: Double,
        fvcValue: Double,
        timestamp: Long
    ): DataRecord {
        val dataPoints = listOf(
            DataPoint(
                pointId = generatePointId(),
                metricName = "PEF",
                value = pefValue.toFloat(),
                unit = "L/min",
                timestamp = timestamp
            ),
            DataPoint(
                pointId = generatePointId(),
                metricName = "FEV1",
                value = fev1Value.toFloat(),
                unit = "L",
                timestamp = timestamp
            ),
            DataPoint(
                pointId = generatePointId(),
                metricName = "FVC",
                value = fvcValue.toFloat(),
                unit = "L",
                timestamp = timestamp
            )
        )
        
        return DataRecord(
            recordId = UUID.randomUUID().toString(),
            deviceId = deviceId,
            connectionId = connectionId,
            dataType = DataType.RESPIRATORY_RATE,
            timestamp = timestamp,
            rawData = "$pefValue$fev1Value$fvcValue$timestamp".toByteArray(),
            dataPoints = dataPoints,
            checksum = generateChecksum("$pefValue$fev1Value$fvcValue$timestamp".toByteArray())
        )
    }
    
    /**
     * Function: 验证数据完整性
     * Parameter: dataRecord - 数据记录
     * Return: Boolean - 数据是否完整
     * Note: 验证解析后的数据是否完整有效
     */
    fun validateDataIntegrity(dataRecord: DataRecord): Boolean {
        return try {
            // 基本字段检查
            if (dataRecord.recordId.isBlank() || 
                dataRecord.connectionId.isBlank() || 
                dataRecord.deviceId.isBlank()) {
                return false
            }
            
            // 原始数据检查
            if (dataRecord.rawData.isEmpty()) {
                return false
            }
            
            // 校验和验证
            val calculatedChecksum = calculateChecksum(dataRecord.rawData)
            if (dataRecord.checksum != null && dataRecord.checksum != calculatedChecksum) {
                Log.w(TAG, "数据校验和不匹配")
                return false
            }
            
            true
        } catch (e: Exception) {
            Log.e(TAG, "数据完整性验证异常", e)
            false
        }
    }
}